package com.umpay.business.consume.impl;

import com.umpay.business.consume.ConsumeBusinessService;
import com.umpay.dict.DataDict;
import com.umpay.dict.XmlData;
import com.umpay.dict.retcode.MerAccessEC;
import com.umpay.dict.retcode.MerBusiEC;
import com.umpay.dto.UMFResponse.Message;
import com.umpay.dto.UMFResponse.Message.Meta;
import com.umpay.dto.merAccess.req.consume.*;
import com.umpay.dto.merAccess.res.consume.ConsumeBalanceRes;
import com.umpay.dto.merAccess.res.consume.ConsumeDebitcardConfirmRes;
import com.umpay.dto.merAccess.res.consume.ConsumeDebitcardRes;
import com.umpay.dto.merAccess.res.consume.ConsumeGeneralOrderRes;
import com.umpay.dto.merBusi.req.consume.*;
import com.umpay.dto.merBusi.req.warrant.WarrantSplitCmdBusi;
import com.umpay.dto.merBusi.res.consume.*;
import com.umpay.dto.payWeb.req.consume.ConsumeNetBankPayReq;
import com.umpay.exception.BusinessException;
import com.umpay.feign.client.ConsumeBusiServerFeignClient;
import com.umpay.util.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/*******************************************************************
 * <br>
 * description : 借记卡消费确认请求业务模块接口处理类
 * @author liuhaidong
 * @date 2018年1月18日 上午11:40:11
 * @version 1.0
 ******************************************************************/
@Service
public class ConsumeBusinessServiceImpl implements ConsumeBusinessService {

	public static final Logger log = LogManager.getLogger(ConsumeBusinessServiceImpl.class);
	@Autowired
	private ConsumeBusiServerFeignClient consumeBusiServerFeignClient;

	@Override
	public Message<ConsumeDebitcardRes> consumeDebitcard(ConsumeDebitcardReq req) {

		log.info(String.format("银行卡消费（快捷），请求参数为:%s", req));
		String merId = StringUtils.trim(req.getMer_id()) ;                       //	            商户号
		String orderId = StringUtils.trim(req.getOrder_id());                   //		商户订单号
		String orderDate = StringUtils.trim(req.getMer_date()) ;                 //		商户订单日期
		String userId = StringUtils.trim(req.getOut_user_id()) ;                 //		付款方用户号
		String userType = StringUtils.trim(req.getOut_user_type()) ;             //		付款方类型
		String payType = StringUtils.trim(req.getPay_type()) ;                   //		支付方式
		String pAgreementId	 = StringUtils.trim(req.getP_agreement_id()) ;       // 	支付协议号
		String amount = StringUtils.trim(req.getAmount()) ;                      //		金额
		String version = StringUtils.trim(req.getVersion()) ;  
		String consigneeName = StringUtils.trim(req.getConsignee_name()) ;       //		收货人
		String consigneeAddress = StringUtils.trim(req.getConsignee_address()) ; //		收货地址
		String consigneePhone	= StringUtils.trim(req.getConsignee_phone()) ;   // 	联系电话
		String remark	= StringUtils.trim(req.getRemark()) ;                    //	           备注信息
		String notifyUrl	= StringUtils.trim(req.getNotify_url()) ;            //	          服务器异步通知路径
		List<SubOrderInfo> subOrderInfo	= req.getSub_order_info() ;              //	         子订单信息

		String bProductId = PropertiesUtil.getBusiStrValue("bsp.bproductid", ""); //		业务产品号
		String pProductId = PropertiesUtil.getBusiStrValue("bsp.consume.pproductid", ""); //		支付产品号
		
		if(StringUtils.trim(DataDict.DEBITCARD).equals(payType)){
			payType=DataDict.PAYTYPE_CONSUME_ORDER_3;
		}else{
			log.info("传入的支付方式有误！");
			throw new BusinessException(MerBusiEC.CONSUMENETBANK_ERR, "【快捷消费下单】传入的支付方式有误！");
		}
		//组织请求merBusi参数
		ConsumeDebitcardBusiReq consumeDebitcardBusiReq = new ConsumeDebitcardBusiReq();
		consumeDebitcardBusiReq.setRpid(RpidUtils.getRpid());//通信流水
		consumeDebitcardBusiReq.setReqDate(TimeUtil.date8());//请求日期
		consumeDebitcardBusiReq.setReqTime(TimeUtil.time6());//请求时间
		consumeDebitcardBusiReq.setOrderId(orderId); //	商户订单号
		consumeDebitcardBusiReq.setOrderDate(orderDate); //	商户订单日期
		consumeDebitcardBusiReq.setMerId(merId); //	商户号
		consumeDebitcardBusiReq.setUserId(userId); //用户编号
		consumeDebitcardBusiReq.setUserType(userType); //	用户类型
		consumeDebitcardBusiReq.setPayType(payType); //	支付类型
		consumeDebitcardBusiReq.setPagreementId(pAgreementId); //	支付协议号
		consumeDebitcardBusiReq.setAmount(amount); //	金额
		consumeDebitcardBusiReq.setVersion(version); //	版本号
		consumeDebitcardBusiReq.setBproductId(bProductId); //	业务产品号
		consumeDebitcardBusiReq.setPproductId(pProductId); //	原子产品号
		consumeDebitcardBusiReq.setConsigneeName(consigneeName); //	收货人
		consumeDebitcardBusiReq.setConsigneeAddress(consigneeAddress); //	收货地址
		consumeDebitcardBusiReq.setConsigneePhone(consigneePhone); //	联系电话
		consumeDebitcardBusiReq.setNotifyUrl(notifyUrl); //	服务器异步通知路径
		consumeDebitcardBusiReq.setRemark(remark); //	备注信息
		consumeDebitcardBusiReq.setSub_order_info(subOrderInfo); //子订单信息
		
		//请求交易模块merBusi
		log.info(String.format("银行卡消费（快捷），调用远程服务接口请求参数为:%s", consumeDebitcardBusiReq));
		Message<ConsumeDebitcardBusiRes> merBusiRes = this.consumeBusiServerFeignClient.merConsumeDebitcard(consumeDebitcardBusiReq);
		log.info(String.format("银行卡消费（快捷），调用远程服务接口获取结果为:%s", merBusiRes));

		// 组织接入模块响应结果
		Message<ConsumeDebitcardRes> resMessage = new Message<ConsumeDebitcardRes>();
		Meta resMeta = new Meta();
		//判断业务响应结果，不为空
		if (merBusiRes != null) {
			Meta metaData = merBusiRes.getMeta();
			String retCode = metaData.getRet_code();
			String retMsg = metaData.getRet_msg();
			resMeta.setRet_code(retCode);//返回码
			resMeta.setRet_msg(retMsg);//返回描述
			
			if(MerAccessEC.SUCCESS.equals(retCode)) {//成功
				ConsumeDebitcardBusiRes resInfo = merBusiRes.getData();
				ConsumeDebitcardRes merAccessRes = new ConsumeDebitcardRes();
				merAccessRes.setMer_id(merId);//商户号
				merAccessRes.setVersion("1.0");//版本号
				merAccessRes.setOrder_id(StringUtils.trim(resInfo.getOrderId()));//		商户订单号
				merAccessRes.setMer_date(StringUtils.trim(resInfo.getOrderDate()));//	商户订单日期
				//merAccessRes.setSettle_amt(StringUtils.trim(resInfo.getSettleAmt()));//	结算金额
				merAccessRes.setTrade_no(StringUtils.trim(resInfo.getTradeNo()));//  联动交易号
				resMessage.setData(merAccessRes);
			} 
		
		} else {//响应结果为空，交易超时
			resMeta.setRet_code(MerAccessEC.MERBUSI_RESPOND_ERR);
			resMeta.setRet_msg("交易结果不明");
		}

		resMessage.setMeta(resMeta);
		resMessage.setLinks(null);
		return resMessage;
	}
	
	
	@Override
	public Message<ConsumeDebitcardConfirmRes> consumeDebitcardConfirm(ConsumeDebitcardConfirmReq req) {

		log.info(String.format("银行卡消费（快捷）确认，请求参数为:%s", req));
		String merId = StringUtils.trim(req.getMer_id()) ;           //	商户号
		String tradeNo = StringUtils.trim(req.getTrade_no());       //		联动交易号
		String amount = StringUtils.trim(req.getAmount() );          //		金额
		String verifyCode = StringUtils.trim(req.getVerify_code() ); //		验证码
		String version = StringUtils.trim(req.getVersion() );          //		金额
		
		String bProductId = PropertiesUtil.getBusiStrValue("bsp.bproductid", "") ; //		业务产品号
		String pProductId = PropertiesUtil.getBusiStrValue("bsp.consume.pproductid", "") ; //		支付产品号
		
		//组织请求merBusi参数
		ConsumeDebitcardConfirmBusiReq consumeDebitcardConfirmBusiReq = new ConsumeDebitcardConfirmBusiReq();
		consumeDebitcardConfirmBusiReq.setMerId(merId);
		consumeDebitcardConfirmBusiReq.setRpid(RpidUtils.getRpid());//  通信流水
		consumeDebitcardConfirmBusiReq.setBproductId(bProductId); //	业务产品号
		consumeDebitcardConfirmBusiReq.setPproductId(pProductId); //	原子产品号
		consumeDebitcardConfirmBusiReq.setTradeNo(tradeNo);       //	联动交易号
		consumeDebitcardConfirmBusiReq.setAmount(amount);         //	金额
		consumeDebitcardConfirmBusiReq.setVersion(version);        //	金额
		consumeDebitcardConfirmBusiReq.setVerifyCode(verifyCode); //	商户订单日期
		consumeDebitcardConfirmBusiReq.setReqDate(TimeUtil.date8());//请求日期
		consumeDebitcardConfirmBusiReq.setReqTime(TimeUtil.time6());//请求时间
		
		//请求交易模块merBusi
		log.info(String.format("银行卡消费（快捷）确认，调用远程服务接口请求参数为:%s", consumeDebitcardConfirmBusiReq));
		Message<ConsumeDebitcardConfirmBusiRes> merBusiRes = this.consumeBusiServerFeignClient.merConsumeDebitcardConfirm(consumeDebitcardConfirmBusiReq);
		log.info(String.format("个人用户注册，调用远程服务接口获取结果为:%s", merBusiRes));

		// 组织接入模块响应结果
		Message<ConsumeDebitcardConfirmRes> resMessage = new Message<ConsumeDebitcardConfirmRes>();
		Meta resMeta = new Meta();
		//判断业务响应结果，不为空
		if (merBusiRes != null) {
			Meta merBusiRet = merBusiRes.getMeta();
			String retCode = merBusiRet.getRet_code();
			String retMsg = merBusiRet.getRet_msg();
			resMeta.setRet_code(retCode);//返回码
			resMeta.setRet_msg(retMsg);//返回描述
			
			if(MerAccessEC.SUCCESS.equals(retCode)) {//成功
				ConsumeDebitcardConfirmBusiRes resInfo = merBusiRes.getData();
				ConsumeDebitcardConfirmRes merAccessRes = new ConsumeDebitcardConfirmRes();
				merAccessRes.setMer_id(merId);//商户号
				merAccessRes.setVersion("1.0");//版本号
				merAccessRes.setSettle_amt(StringUtils.trim(resInfo.getSettleAmt()));//	结算金额
				merAccessRes.setOrder_id(StringUtils.trim(resInfo.getOrderId()));//		商户订单号
				merAccessRes.setMer_date(StringUtils.trim(resInfo.getOrderDate()));//	商户订单日期
				merAccessRes.setMer_check_date(StringUtils.trim(resInfo.getMerCheckDate()));//		商户用户标识
				resMessage.setData(merAccessRes);
			} 
		
		} else {//响应结果为空，交易超时
			resMeta.setRet_code(MerAccessEC.MERBUSI_RESPOND_ERR);
			resMeta.setRet_msg("交易结果不明");
		}

		resMessage.setMeta(resMeta);
		resMessage.setLinks(null);
		return resMessage;
	}
	
	@Override
	public void consumeNetBank(ConsumeNetBankReq req) {
		
		ConsumeNetBankPayReq consumeNetBankPayReq = new ConsumeNetBankPayReq();
		
		//请求业务系统下单
		consumeNetBankOrder(req,consumeNetBankPayReq);
		
		//组织请求payWeb数据
		getRequstConsumeNetBankPayData(req,consumeNetBankPayReq);
		
		//请求payweb进行支付
		consumeNetBankPay(consumeNetBankPayReq);
	}

	private void consumeNetBankPay(ConsumeNetBankPayReq consumeNetBankPayReq) {
		Map<String, Object> reqMap = new HashMap<String, Object>();
		reqMap.put(XmlData.RPID, StringUtils.trim(consumeNetBankPayReq.getRpid()));
		reqMap.put(XmlData.MERID, StringUtils.trim(consumeNetBankPayReq.getMerId()));
		reqMap.put(XmlData.AMOUNT, StringUtils.trim(consumeNetBankPayReq.getAmount()));
		reqMap.put(XmlData.ORDERDATE, StringUtils.trim(consumeNetBankPayReq.getOrderDate()));
		reqMap.put(XmlData.ORDERID, StringUtils.trim(consumeNetBankPayReq.getOrderId()));
		reqMap.put(XmlData.REQDATE, TimeUtil.date8());
		reqMap.put(XmlData.REQTIME, TimeUtil.time6());
		
		String url = PropertiesUtil.getBusiStrValue("acc.rest2.service.queryAccountBalance","");
		
		if(StringUtils.isEmpty(url)){
			log.info("【请求账户】请求支付网关未配置请求地址");
			throw new BusinessException(MerBusiEC.REQUESTURL_NOTEXIT,"服务地址未配置");
		}
		Map<String, Object> retMap = RemoteServiceUtils.callRemoteServiceByPost(url,reqMap);
		
		if(retMap==null){
			log.info("【网银消费支付】请求网银web异常！");
			throw new BusinessException(MerAccessEC.CONSUMENETBANK_PAY_ERR, "请求网银web异常！");
		}else{
			String retCode = StringUtils.trim(retMap.get(XmlData.RETCODE));
			if(!MerAccessEC.SUCCESS.equals(retCode)){
				log.info("【网银消费支付】请求网银web失败！");
				throw new BusinessException(MerAccessEC.CONSUMENETBANK_PAY_FAIL, "请求网银web失败！");
			}
			log.info("【网银消费支付】请求网银web成功！");
		}
	}

	private void getRequstConsumeNetBankPayData(ConsumeNetBankReq req, ConsumeNetBankPayReq consumeNetBankPayReq) {
		
		consumeNetBankPayReq.setAmount(req.getAmount());
		consumeNetBankPayReq.setMerId(req.getMer_id());
		consumeNetBankPayReq.setOrderDate(req.getMer_date());
		consumeNetBankPayReq.setOrderId(req.getOrder_id());
	}


	/*private void consumeNetBankPay(ConsumeNetBankReq req) {
		Map<String, Object> reqMap = new HashMap<String, Object>();
		reqMap.put(XmlData.RPID, StringUtil.trim((req.get(XmlData.RPID))));
		reqMap.put(XmlData.MERID, StringUtil.trim(req.get(XmlData.MERID)));
		reqMap.put(XmlData.REQDATE, TimeUtil.date8());
		reqMap.put(XmlData.REQTIME, TimeUtil.time6());
		reqMap.put(XmlData.INSTID, TimeUtil.time6());
		
		String url = propertyUtil.getProperty("acc.rest2.service.queryAccountBalance");
		
		if(StringUtils.isEmpty(url)){
			log.info("【请求账户】请求支付网关未配置请求地址");
			throw new BusinessException(MerBusiEC.REQUESTURL_NOTEXIT,"服务地址未配置");
		}
		Map<String, Object> retMap = RemoteServiceUtils.callRemoteServiceByPost(url,reqMap);
		
	}*/


	private void consumeNetBankOrder(ConsumeNetBankReq req, ConsumeNetBankPayReq consumeNetBankPayReq) {
		log.info(String.format("网银消费（快捷），请求参数为:%s", req));
		String rpid = RpidUtils.getRpid();
		String merId = StringUtils.trim(req.getMer_id()) ;                       //	            商户号
		String orderId = StringUtils.trim(req.getOrder_id() );                   //		商户订单号
		String orderDate = StringUtils.trim(req.getMer_date()) ;                 //		商户订单日期
		String userId = StringUtils.trim(req.getOut_user_id()) ;                 //		付款方用户号
		String userType = StringUtils.trim(req.getOut_user_type()) ;             //		付款方类型
		String payType = StringUtils.trim(req.getPay_type()) ;                   //		支付方式
		String gateId	 = StringUtils.trim(req.getGate_id()) ;       // 	发卡行编号
		String amount = StringUtils.trim(req.getAmount()) ;                      //		金额
		String consigneeName = StringUtils.trim(req.getConsignee_name()) ;       //		收货人
		String consigneeAddress = StringUtils.trim(req.getConsignee_address()) ; //		收货地址
		String consigneePhone	= StringUtils.trim(req.getConsignee_phone()) ;   // 	联系电话
		String remark	= StringUtils.trim(req.getRemark()) ;                    //	           备注信息
		String retUrl	= StringUtils.trim(req.getRet_url()) ;            //	          服务器异步前台通知路径
		String notifyUrl	= StringUtils.trim(req.getNotify_url()) ;            //	          服务器异步通知路径
		List<SubOrderInfo> subOrderInfo	= req.getSub_order_info() ;              //	         子订单信息
		String bProductId = PropertiesUtil.getBusiStrValue("bsp.bproductid", "") ; //		业务产品号
		String pProductId = PropertiesUtil.getBusiStrValue("bsp.consume.pproductid", "") ; //		支付产品号
		
		if(DataDict.B2CDEBITBANK.equals(payType)){
			payType=DataDict.PAY_TYPE_B2CBANK_2;
		}else if(DataDict.B2BBANK.equals(payType)){
			payType=DataDict.PAY_TYPE_B2BBANK_1;
		}else{
			log.info("传入的支付方式有误！");
			throw new BusinessException(MerBusiEC.CONSUMENETBANK_ERR, "【网银消费下单】传入的支付方式有误！");
		}
		//组织请求merBusi参数
		ConsumeNetBankBusiReq consumeNetBankBusiReq = new ConsumeNetBankBusiReq();
		consumeNetBankBusiReq.setRpid(rpid);//通信流水
		consumeNetBankPayReq.setRpid(rpid);//统一设置通信流水
		consumeNetBankBusiReq.setReqDate(TimeUtil.date8());//请求日期
		consumeNetBankBusiReq.setReqTime(TimeUtil.time6());//请求时间
		consumeNetBankBusiReq.setOrderId(orderId); //	商户订单号
		consumeNetBankBusiReq.setOrderDate(orderDate); //	商户订单日期
		consumeNetBankBusiReq.setMerId(merId); //	商户号
		consumeNetBankBusiReq.setUserId(userId); //用户编号
		consumeNetBankBusiReq.setUserType(userType); //	用户类型
		consumeNetBankBusiReq.setPayType(payType); //	支付类型
		consumeNetBankBusiReq.setGateId(gateId); //	支付协议号
		consumeNetBankBusiReq.setAmount(amount); //	金额
		consumeNetBankBusiReq.setBproductId(bProductId); //	业务产品号
		consumeNetBankBusiReq.setPproductId(pProductId); //	原子产品号
		consumeNetBankBusiReq.setConsigneeName(consigneeName); //	收货人
		consumeNetBankBusiReq.setConsigneeAddress(consigneeAddress); //	收货地址
		consumeNetBankBusiReq.setConsigneePhone(consigneePhone); //	联系电话
		consumeNetBankBusiReq.setNotifyUrl(notifyUrl); //	服务器异步通知路径
		consumeNetBankBusiReq.setRetUrl(retUrl); //	服务器异步通知路径
		consumeNetBankBusiReq.setRemark(remark); //	备注信息
		consumeNetBankBusiReq.setSub_order_info(subOrderInfo); //子订单信息
		
		//请求交易模块merBusi
		log.info(String.format("银行卡消费（网银），调用远程服务接口请求参数为:%s", consumeNetBankBusiReq));
		Message<ConsumeNetBankBusiRes> merBusiRes = this.consumeBusiServerFeignClient.merConsumeNetBank(consumeNetBankBusiReq);
		log.info(String.format("银行卡消费（网银），调用远程服务接口获取结果为:%s", merBusiRes));
		
		if (merBusiRes != null) {
			Meta metaData = merBusiRes.getMeta();
			ConsumeNetBankBusiRes res = merBusiRes.getData();
			String retCode = metaData.getRet_code();
			String retMsg = metaData.getRet_msg();
			if(!MerAccessEC.SUCCESS.equals(retCode)) {//成功
				log.info("【银行卡消费（网银）下单】下单失败！");
				throw new BusinessException(retCode, retMsg);
			}
			consumeNetBankPayReq.setTrace(res.getTrace());
			consumeNetBankPayReq.setTradeNo(res.getTradeNo());
		} else {//响应结果为空，交易超时
			log.info("【银行卡消费（网银）下单】下单失败！");
			throw new BusinessException(MerAccessEC.CONSUMENETBANK_ORDER_FAIL, "下单失败！");
		}
		log.info("【银行卡消费（网银）下单】下单成功！");
	}
	
	@Override
	public Message<ConsumeBalanceRes> consumeBalance(ConsumeBalanceReq req) {

		log.info(String.format("余额支付，请求参数为:%s", req));
		String merId = StringUtils.trim(req.getMer_id()) ;                       //	            商户号
		String userId = StringUtils.trim(req.getUser_id()) ;                     //		付款方用户号
		String accType;                   
		if(StringUtils.isEmpty(req.getAcc_type())) {           //	   账户类型为空默认208
			accType = DataDict.PAYACCTYPE_208;
		}else {
			accType = StringUtils.trim(req.getAcc_type());
		}
		String merTrace = StringUtils.trim(req.getMer_trace());                  //	             商户流水号
		String tradeNo = StringUtils.trim(req.getTrade_no()) ;                   //		订单号				
		String amount = StringUtils.trim(req.getAmount()) ;                      //		支付金额
		String version = StringUtils.trim(req.getVersion()) ;  
		String remark = StringUtils.trim(req.getRemark()) ;                      //	           备注信息
		String notifyUrl = StringUtils.trim(req.getNotify_url()) ;               //	          服务器异步通知路径

		String bProductId = PropertiesUtil.getBusiStrValue("bsp.bproductid", "") ; //		业务产品号
		String pProductId = PropertiesUtil.getBusiStrValue("bsp.balanceConsume.pproductid", "") ; //		支付产品号
	    String accessType = StringUtils.trim(req.getAccessType());  //接入类型
 		String accessName = StringUtils.trim(req.getAccessName());  //接入名称
 		String depBankMerId = StringUtils.trim(req.getDepBankMerId());  //存管行
		//组织请求merBusi参数
		ConsumeBalanceBusiReq consumeBalanceBusiReq = new ConsumeBalanceBusiReq();
		consumeBalanceBusiReq.setRpid(RpidUtils.getRpid());//通信流水
		consumeBalanceBusiReq.setReqDate(TimeUtil.date8());//请求日期
		consumeBalanceBusiReq.setReqTime(TimeUtil.time6());//请求时间
		consumeBalanceBusiReq.setMerId(merId); //商户流水号
		consumeBalanceBusiReq.setUserId(userId); //用户编号
		consumeBalanceBusiReq.setAccType(accType);//账户类型
		consumeBalanceBusiReq.setMerTrace(merTrace); //	商户流水号
		consumeBalanceBusiReq.setTradeNo(tradeNo); //订单交易号
		consumeBalanceBusiReq.setAmount(amount); //	金额
		consumeBalanceBusiReq.setVersion(version); //	版本号
		consumeBalanceBusiReq.setbProductId(bProductId); //	业务产品号
		consumeBalanceBusiReq.setpProductId(pProductId); //	原子产品号
		consumeBalanceBusiReq.setNotifyUrl(notifyUrl); //	服务器异步通知路径
		consumeBalanceBusiReq.setRemark(remark); //	备注信息
		consumeBalanceBusiReq.setAccessName(accessName);
		consumeBalanceBusiReq.setAccessType(accessType);
		consumeBalanceBusiReq.setDepBankMerId(depBankMerId);
		//请求交易模块merBusi
		log.info(String.format("余额支付，调用远程服务接口请求参数为:%s", consumeBalanceBusiReq));
		Message<ConsumeBalanceBusiRes> merBusiRes = this.consumeBusiServerFeignClient.merConsumeBalance(consumeBalanceBusiReq);
		log.info(String.format("余额支付，调用远程服务接口获取结果为:%s", merBusiRes));

		// 组织接入模块响应结果
		Message<ConsumeBalanceRes> resMessage = new Message<ConsumeBalanceRes>();
		Meta resMeta = new Meta();
		//判断业务响应结果，不为空
		if (merBusiRes != null) {
			Meta metaData = merBusiRes.getMeta();
			String retCode = StringUtils.trim(metaData.getRet_code());
			String retMsg = StringUtils.trim(metaData.getRet_msg());
			resMeta.setRet_code(retCode);//返回码
			resMeta.setRet_msg(retMsg);//返回描述
			
			if(StringUtils.isEmpty(retCode)) {
				resMeta.setRet_code(MerAccessEC.MERBUSI_RESPOND_ERR);
				resMeta.setRet_msg("交易结果不明");
				
			}else if(MerAccessEC.SUCCESS.equals(retCode)) {//成功				
				ConsumeBalanceBusiRes resInfo = merBusiRes.getData();
				ConsumeBalanceRes merAccessRes = new ConsumeBalanceRes();
				merAccessRes.setMer_id(merId);//商户号
				merAccessRes.setVersion(DataDict.VERSION);//版本号
				merAccessRes.setMer_trace(StringUtils.trim(resInfo.getMerTrace()));//		商户流水号
				merAccessRes.setTrade_no(StringUtils.trim(resInfo.getTradeNo()));//  联动交易号
				merAccessRes.setAmount(StringUtils.trim(resInfo.getAmount()));//	支付金额
				merAccessRes.setSettle_amt(StringUtils.trim(resInfo.getSettleAmt()));//	结算金额
				merAccessRes.setMer_check_date(StringUtils.trim(resInfo.getMerCheckDate()));//	平台对账日期
				resMeta.setRet_msg("支付成功");//返回描述
				
				resMessage.setData(merAccessRes);
			    } 		
		 } else {//响应结果为空，交易超时
			resMeta.setRet_code(MerAccessEC.MERBUSI_RESPOND_ERR);
			resMeta.setRet_msg("交易结果不明");
		 }

		resMessage.setMeta(resMeta);
		resMessage.setLinks(null);
		return resMessage;
	}
	
	/* ********************************************
	 * method name   : consumeGeneralOrder 
	 * modified      : ncc ,  2018年3月15日 下午3:24:32
	 * modified      : zhangru ,   2019年1月7日 下午5:25:04 增加虚拟支付
	 * @see          : @see com.umpay.business.consume.ConsumeBusinessService#generalOrder(com.umpay.dto.merAccess.req.consume.GeneralOrderReq)
	 * ********************************************/     
	@Override
	public Message<ConsumeGeneralOrderRes> consumeGeneralOrder(ConsumeGeneralOrderReq req) {
		log.info(String.format("业务下单，请求参数为:%s", req));
		String orderType = StringUtils.trim(req.getOrder_type()) ;              //		订单类型
    	String orderFlag = DataDict.ORDER_FLAG_0 ;//默认不走支付流程
    	if(orderType.length()>1) {
    		orderFlag = orderType.substring(0, 1);
    	}
        if(DataDict.ORDER_FLAG_0.equals(orderFlag)) {//业务下单
        	return generalOrder(req);
        } else if(DataDict.ORDER_FLAG_1.equals(orderFlag)){//虚拟支付流程
        	return consumeVirtualPayment(req);
        } else {
        	throw new BusinessException(MerAccessEC.REQPARAM_ERR, "请求参数order_type格式或值不正确");
        }
	}
	
	/**
	 * description : 原业务下单
	 * @author zhangru
	 * @date 2019年1月7日 下午5:25:04
	 * @version 1.0
	**/
	private Message<ConsumeGeneralOrderRes> generalOrder(ConsumeGeneralOrderReq req) {	
		String merId = StringUtils.trim(req.getMer_id()) ;                       //	            商户号
		String orderId = StringUtils.trim(req.getOrder_id() );                   //		商户订单号
		String orderDate = StringUtils.trim(req.getMer_date()) ;                 //		商户订单日期
		String userId = StringUtils.trim(req.getOut_user_id()) ;                 //		付款方用户号
		String userType = StringUtils.trim(req.getOut_user_type()) ;             //		付款方类型
		String orderType = StringUtils.trim(req.getOrder_type()) ;              //		订单类型
		String orderChannel = StringUtils.trim(req.getOrder_channel()) ;         //		交易渠道
		String amount = StringUtils.trim(req.getAmount()) ;                      //		金额
		String version = StringUtils.trim(req.getVersion()) ;  
		String consigneeName = StringUtils.trim(req.getConsignee_name()) ;       //		收货人
		String consigneeAddress = StringUtils.trim(req.getConsignee_address()) ; //		收货地址
		String consigneePhone	= StringUtils.trim(req.getConsignee_phone()) ;   // 	联系电话
		String remark	= StringUtils.trim(req.getRemark()) ;                    //	           备注信息
		String notifyUrl	= StringUtils.trim(req.getNotify_url()) ;            //	          服务器异步通知路径
		List<SubOrderInfo> subOrderInfo	= req.getSub_order_info() ;              //	         子订单信息
		String bProductId = PropertiesUtil.getBusiStrValue("bsp.bproductid", "") ; //		业务产品号
		String pProductId = PropertiesUtil.getBusiStrValue(String.format("bsp.consumeGeneralOrder.pproductid.orderType.%s", orderType), "") ; //支付产品号
		
		String settleAmt = StringUtils.trim(req.getSettle_amt()) ;                      //	结算金额
		String payType = StringUtils.trim(req.getPay_type());
		if(StringUtils.isNotEmpty(payType)) {
			throw new BusinessException(MerAccessEC.REQPARAM_ERR, String.format("请求参数pay_type=[%s]必须为空",payType));
		}
		if(StringUtils.isNotEmpty(settleAmt)) {
			throw new BusinessException(MerAccessEC.REQPARAM_ERR, String.format("请求参数settle_amt=[%s]必须为空",settleAmt));
		}
		
		//组织请求merBusi参数
		ConsumeGeneralOrderBusiReq consumeGeneralOrderBusiReq = new ConsumeGeneralOrderBusiReq();
		consumeGeneralOrderBusiReq.setRpid(RpidUtils.getRpid());//通信流水
		consumeGeneralOrderBusiReq.setReqDate(TimeUtil.date8());//请求日期
		consumeGeneralOrderBusiReq.setReqTime(TimeUtil.time6());//请求时间
		consumeGeneralOrderBusiReq.setOrderId(orderId); //	商户订单号
		consumeGeneralOrderBusiReq.setOrderDate(orderDate); //	商户订单日期
		consumeGeneralOrderBusiReq.setMerId(merId); //	商户号
		consumeGeneralOrderBusiReq.setUserId(userId); //用户编号
		consumeGeneralOrderBusiReq.setUserType(userType); //	用户类型
		consumeGeneralOrderBusiReq.setAmount(amount); //	金额
		consumeGeneralOrderBusiReq.setOrderType(orderType); // 订单类型
		consumeGeneralOrderBusiReq.setOrderChannel(orderChannel); // 交易渠道
		consumeGeneralOrderBusiReq.setVersion(version); //	版本号
		consumeGeneralOrderBusiReq.setBproductId(bProductId); //	业务产品号
		consumeGeneralOrderBusiReq.setPproductId(pProductId); //	支付产品号
		consumeGeneralOrderBusiReq.setConsigneeName(consigneeName); //	收货人
		consumeGeneralOrderBusiReq.setConsigneeAddress(consigneeAddress); //	收货地址
		consumeGeneralOrderBusiReq.setConsigneePhone(consigneePhone); //	联系电话
		consumeGeneralOrderBusiReq.setNotifyUrl(notifyUrl); //	服务器异步通知路径
		consumeGeneralOrderBusiReq.setRetUrl(StringUtils.trim(req.getRet_url()));
		consumeGeneralOrderBusiReq.setRemark(remark); //	备注信息
		consumeGeneralOrderBusiReq.setSub_order_info(subOrderInfo); //子订单信息
		consumeGeneralOrderBusiReq.setSplitCmdBusi(convertSplitCmdBusiList(req.getSplit_cmd(), merId));
		//请求交易模块merBusi
		log.info(String.format("业务下单，调用远程服务接口请求参数为:%s", consumeGeneralOrderBusiReq));
		Message<ConsumeGeneralOrderBusiRes> merBusiRes = this.consumeBusiServerFeignClient.consumeGeneralOrder(consumeGeneralOrderBusiReq);
		log.info(String.format("业务下单，调用远程服务接口获取结果为:%s", merBusiRes));

		// 组织接入模块响应结果
		Message<ConsumeGeneralOrderRes> resMessage = new Message<ConsumeGeneralOrderRes>();
		Meta resMeta = new Meta();
		//判断业务响应结果，不为空
		if (merBusiRes != null) {
			Meta metaData = merBusiRes.getMeta();
			String retCode = metaData.getRet_code();
			String retMsg = metaData.getRet_msg();
			resMeta.setRet_code(retCode);//返回码
			resMeta.setRet_msg(retMsg);//返回描述
			
			if(MerAccessEC.SUCCESS.equals(retCode)) {//成功
				ConsumeGeneralOrderBusiRes resInfo = merBusiRes.getData();
				ConsumeGeneralOrderRes merAccessRes = new ConsumeGeneralOrderRes();
				merAccessRes.setMer_id(merId);//商户号
				merAccessRes.setVersion("1.0");//版本号
				merAccessRes.setOrder_id(StringUtils.trim(resInfo.getOrderId()));//		商户订单号
				merAccessRes.setMer_date(StringUtils.trim(resInfo.getOrderDate()));//	商户订单日期
				merAccessRes.setTrade_no(StringUtils.trim(resInfo.getTradeNo()));//  联动交易号
				resMessage.setData(merAccessRes);
			} 
		
		} else {//响应结果为空，交易超时
			resMeta.setRet_code(MerAccessEC.MERBUSI_RESPOND_ERR);
			resMeta.setRet_msg("交易结果不明");
		}

		resMessage.setMeta(resMeta);
		resMessage.setLinks(null);
		return resMessage;
	}

	/**
	 * description : 虚拟支付
	 * @author zhangru
	 * @date 2019年1月7日 下午4:10:12
	 * @version 1.0
	**/
	private Message<ConsumeGeneralOrderRes> consumeVirtualPayment(ConsumeGeneralOrderReq req) {
		log.info(String.format("虚拟支付，请求参数为:%s", req));
		//请求参数校验
		checkConsumeVirtualPaymentReqData(req);
		
		//获取请求参数
		String merId = StringUtils.trim(req.getMer_id()) ;                       //	            商户号
		String orderId = StringUtils.trim(req.getOrder_id() );                   //		商户订单号
		String orderDate = StringUtils.trim(req.getMer_date()) ;                 //		商户订单日期
		String userId = StringUtils.trim(req.getOut_user_id()) ;                 //		付款方用户号
		String userType = StringUtils.trim(req.getOut_user_type()) ;             //		付款方类型
		String orderChannel = StringUtils.trim(req.getOrder_channel()) ;         //		交易渠道
		String amount = StringUtils.trim(req.getAmount()) ;                      //		金额
		String settleAmt = StringUtils.trim(req.getSettle_amt()) ;                      //	结算金额
		String version = StringUtils.trim(req.getVersion()) ;  
		String remark	= StringUtils.trim(req.getRemark()) ;                    //	           备注信息
		String notifyUrl	= StringUtils.trim(req.getNotify_url()) ;            //	          服务器异步通知路径
		String retUrl	= StringUtils.trim(req.getRet_url());            //	          服务器异步通知路径
		String accessType	= StringUtils.trim(req.getAccessType()) ;  
		String accessName	= StringUtils.trim(req.getAccessName());
		String depBankMerId	= StringUtils.trim(req.getDepBankMerId()) ; 
		String pay_type = StringUtils.trim(req.getPay_type());
		String consigneeName = StringUtils.trim(req.getConsignee_name()) ;       //		收货人
		String consigneeAddress = StringUtils.trim(req.getConsignee_address()) ; //		收货地址
		String consigneePhone	= StringUtils.trim(req.getConsignee_phone()) ;   // 	联系电话
		String orderType = StringUtils.trim(req.getOrder_type()).substring(1) ;              //		订单类型
		List<SubOrderInfo> subOrderInfo	= req.getSub_order_info() ;              //	         子订单信息
		String bProductId = PropertiesUtil.getBusiStrValue("bsp.bproductid", "") ; //		业务产品号
		String pProductId = PropertiesUtil.getBusiStrValue("bsp.consume.fileNotify.pproductid", "") ; //虚拟支付产品号
		String productId = PropertiesUtil.getBusiStrValue(String.format("bsp.consumeGeneralOrder.pproductid.orderType.%s", orderType), "") ; //校验订单类型的支付产品号
		String payType = payTypeConvert(pay_type);//支付类型转换
		
		//组织请求merBusi参数
		ConsumeVirtualPaymentBusiReq busiReq = new ConsumeVirtualPaymentBusiReq();
		busiReq.setRpid(RpidUtils.getRpid());//通信流水
		busiReq.setReqDate(TimeUtil.date8());//请求日期
		busiReq.setReqTime(TimeUtil.time6());//请求时间
		busiReq.setVersion(version);//请求时间
		busiReq.setOrderId(orderId); //	商户订单号
		busiReq.setOrderDate(orderDate); //	商户订单日期
		busiReq.setMerId(merId); //	商户号
		busiReq.setOutUserId(userId); //用户编号
		busiReq.setOutUserType(userType); //	用户类型
		busiReq.setPayType(payType); //	支付类型
		busiReq.setAmount(amount); //	金额
		busiReq.setSettleAmt(settleAmt); //	结算金额
		busiReq.setOrderType(orderType); // 订单类型
		busiReq.setOrderChannel(orderChannel); // 交易渠道
		busiReq.setVersion(version); //	版本号
		busiReq.setBproductId(bProductId); //	业务产品号
		busiReq.setProductId(productId);; //	支付产品号
		busiReq.setPproductId(pProductId); //	支付产品号
		busiReq.setNotifyUrl(notifyUrl); //	服务器异步通知路径
		busiReq.setRetUrl(retUrl); //通知路径
		busiReq.setRemark(remark); //	备注信息
		busiReq.setConsigneeName(consigneeName); //	收货人
		busiReq.setConsigneeAddress(consigneeAddress); //	收货地址
		busiReq.setConsigneePhone(consigneePhone); //	联系电话
		busiReq.setAccessType(accessType);
		busiReq.setAccessName(accessName);
		busiReq.setDepBankMerId(depBankMerId);
		busiReq.setSub_order_info(subOrderInfo); //子订单信息
		busiReq.setSplitCmdBusi(convertSplitCmdBusiList(req.getSplit_cmd(), merId));
		//请求交易模块merBusi
		log.info(String.format("虚拟支付，调用远程服务接口请求参数为:%s", busiReq));
		Message<ConsumeVirtualPaymentBusiRes> merBusiRes = this.consumeBusiServerFeignClient.consumeVirtualPayment(busiReq);
		log.info(String.format("虚拟支付，调用远程服务接口获取结果为:%s", merBusiRes));

		// 组织接入模块响应结果
    	Message<ConsumeGeneralOrderRes> resMessage = new Message<ConsumeGeneralOrderRes>();
    	Meta resMeta = new Meta();
		//判断业务响应结果，不为空
		if (merBusiRes != null) {
			Meta metaData = merBusiRes.getMeta();
			String retCode = metaData.getRet_code();
			String retMsg = metaData.getRet_msg();
			resMeta.setRet_code(retCode);//返回码
			resMeta.setRet_msg(retMsg);//返回描述
			
			if(MerAccessEC.SUCCESS.equals(retCode)) {//成功
				ConsumeVirtualPaymentBusiRes resInfo = merBusiRes.getData();
				ConsumeGeneralOrderRes merAccessRes = new ConsumeGeneralOrderRes();
    			merAccessRes.setMer_id(merId);//商户号
    			merAccessRes.setVersion("1.0");//版本号
    			merAccessRes.setOrder_id(StringUtils.trim(resInfo.getOrderId()));//		商户订单号
    			merAccessRes.setMer_date(StringUtils.trim(resInfo.getOrderDate()));//	商户订单日期
    			merAccessRes.setTrade_no(StringUtils.trim(resInfo.getTradeNo()));//  联动交易号
    			resMessage.setData(merAccessRes);
			} 
		
		} else {//响应结果为空，交易超时
			resMeta.setRet_code(MerAccessEC.MERBUSI_RESPOND_ERR);
			resMeta.setRet_msg("交易结果不明");
		}

		resMessage.setMeta(resMeta);
		resMessage.setLinks(null);
		return resMessage;
	}
		
	/**
	 * description : 分账数据转换
	 * @author zhangru
	 * @date 2019年1月7日 下午5:09:55
	 * @version 1.0
	**/
	private List<WarrantSplitCmdBusi> convertSplitCmdBusiList(List<WarrantSplitCmd>  splitCmdList,String merId) {
    	List<WarrantSplitCmdBusi> splitCmdBusiList = null;
    	if (StringUtils.isNotEmpty(splitCmdList) && splitCmdList.size()> 0) {
    		splitCmdBusiList = new ArrayList<WarrantSplitCmdBusi>();
    		for (WarrantSplitCmd splitCmd : splitCmdList) {
    			WarrantSplitCmdBusi sdb = new WarrantSplitCmdBusi();
    			sdb.setSplitOrderId(StringUtils.trim(splitCmd.getSplit_order_id())); // 商户订单号
    			sdb.setSplitOrderDate(StringUtils.trim(splitCmd.getSplit_mer_date())); // 商户订单日期
    			sdb.setInUserId(StringUtils.trim(splitCmd.getIn_user_id())); // 收款方用户号
    			String inAccType = StringUtils.trim(splitCmd.getIn_acc_type()); //账户类型
    			//不传默认赋值
    			if(StringUtils.isEmpty(inAccType)){
    				//判断是否分账方为平台
    				if(merId.equals(StringUtils.trim(splitCmd.getIn_user_id()))) {
    					//平台方
    					sdb.setInAccType(DataDict.PAYACCTYPE_203);
    				}else {
    					//会员
    					sdb.setInAccType(DataDict.PAYACCTYPE_208);
    				}
    			}else {
    				sdb.setInAccType(StringUtils.trim(splitCmd.getIn_acc_type())); // 收款方账户类型
    			}
    			sdb.setSplitAmount(StringUtils.trim(splitCmd.getSplit_amount())); // 金额
    			sdb.setSplitCategory(StringUtils.trim(splitCmd.getSplit_category()));
    			sdb.setPercent(StringUtils.trim(splitCmd.getPercent()));
    			sdb.setIsFeePayer(StringUtils.trim(splitCmd.getIs_fee_payer()));
    			log.info(String.format("组织分账子订单数据: %s", sdb));
    			splitCmdBusiList.add(sdb);
    		}
    	}
		return splitCmdBusiList;
	}

	
	
	/**
	 * description :虚拟支付请求参数校验
	 * @author zhangru
	 * @date 2019年1月7日 下午4:22:49
	 * @version 1.0
	**/
	private void checkConsumeVirtualPaymentReqData(ConsumeGeneralOrderReq req) {
		String amount = StringUtils.trim(req.getAmount()) ;                      //		金额
		String settleAmt = StringUtils.trim(req.getSettle_amt()) ;                      //	结算金额
		List<WarrantSplitCmd>  splitCmdList = req.getSplit_cmd();
		String payType = StringUtils.trim(req.getPay_type());
		String virtualOrderType = StringUtils.trim(req.getOrder_type()) ;              //		订单类型
		String orderType;
		
		if(StringUtils.isEmpty(payType)) {
			throw new BusinessException(MerAccessEC.REQPARAM_ERR, String.format("请求参数pay_type=[%s]不能为空",payType));
		}
		if(StringUtils.isEmpty(settleAmt)) {
			throw new BusinessException(MerAccessEC.REQPARAM_ERR, String.format("请求参数settle_amt=[%s]不能为空",settleAmt));
		}
		if(virtualOrderType.length()==2) {
			orderType = virtualOrderType.substring(1);//第二位是订单类型
		}else {
			log.info(String.format("订单类型[%s]不正确",virtualOrderType));
			throw new BusinessException(MerAccessEC.REQPARAM_ERR, String.format("订单类型[%s]不正确",virtualOrderType));
		}
		
		//订单类型为2、3时，分账子订单必传
		if(DataDict.ORDER_TYPE_2.equals(orderType) || DataDict.ORDER_TYPE_3.equals(orderType)) {
			if (StringUtils.isEmpty(splitCmdList) || splitCmdList.size()<= 0) {
				log.info(String.format("订单类型为[%s]时，分账子订单必传",virtualOrderType));
				throw new BusinessException(MerAccessEC.REQPARAM_ERR, String.format("订单类型为[%s]时，分账子订单必传",virtualOrderType));
			}
		}
		
		//判断订单金额与结算金额是否相等
		if(!amount.equals(settleAmt)) {
			log.info(String.format("虚拟支付，订单金额与结算金额不一致，订单金额[%s]，结算金额[%s]", amount,settleAmt));
			throw new BusinessException(MerAccessEC.REQPARAM_ERR, String.format("虚拟支付，订单金额与结算金额不一致，订单金额[%s]，结算金额[%s]", amount,settleAmt));
		}
	}

	/**
	 * description : 支付类型转换
	 * @author zhangru
	 * @date 2018年12月24日 下午7:57:45
	 * @version 1.0
	**/
	private String payTypeConvert(String reqPayType) {
		PropertyUtil propertyUtil = (PropertyUtil)SpringUtil.getBean("propertyUtil");
		String payTypeInfo = propertyUtil.getProperty("b2b.paytype.mapping");// 配置文件取出新的映射关系
		log.info("传入的支付类型->联动的支付类型" + payTypeInfo);
		Map<String, String> payTypesMap = new HashMap<String, String>();
		if(StringUtils.isNotEmpty(payTypeInfo)){
	        String[] payTypeInfos = payTypeInfo.split(";");
	        if(payTypeInfos != null && payTypeInfos.length > 0){
	          for (String payTypes : payTypeInfos){
	              String[] payTypeMap = payTypes.split(",");
	                  if (payTypeMap != null && payTypeMap.length > 1){
	                	  payTypesMap.put(payTypeMap[0], payTypeMap[1]);
	               }
	            }
	        }
       } 
	   String payType = payTypesMap.get(reqPayType);
	   if(StringUtils.isEmpty(payType)){
		   payType = DataDict.PAYTYPE_TRANS_99;
		   log.info(String.format("虚拟支付，未找到商户传入的支付类型[%s]的转换关系，默认为[%s]", reqPayType,payType));
	   }
	   return payType;
	}
}
